home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / ansi / help_7n1.zip / CAPTURE.ASM next >
Assembly Source File  |  1987-10-30  |  16KB  |  476 lines

  1. ;from VOL7N1.ARC, PC Magazine Jan 88?
  2. ;----------------------------------------------------------------------
  3. ; CAPTURE is a resident utility which copies an 80x25 screen buffer
  4. ; to a file.  Activate CAPTURE by pressing ALT-C or any other hot
  5. ; key combination defined by the symbols HOTKEY and SHIFT_MASK.
  6. ; The filename will be SCREEN.n. The extension begins with .000 and
  7. ; is incremented by one each time CAPTURE is activated.
  8. ;-----------------------------------------------------------------------
  9. ; BIOS_SEG is located in the ROM-BIOS data area
  10. ;-----------------------------------------------------------------------
  11. BIOS_SEG    SEGMENT AT 0040H
  12.  
  13.         ORG    0017H
  14. KB_FLAG        DB    ?        ;BIOS keyboard shift status
  15.         ORG    004AH
  16. CRT_COLS    DB    ?        ;Current number of screen columns
  17.         ORG    0050H
  18. CURSOR_POSN    DW    8 DUP(?)    ;Current cursor location
  19.         ORG    0062H
  20. ACTIVE_PAGE    DB    ?        ;Active page for CGA and EGA
  21.  
  22. BIOS_SEG    ENDS
  23.  
  24. ;=======================================================================
  25. CSEG        SEGMENT
  26.         ASSUME  CS:CSEG, DS:CSEG, ES:CSEG
  27.         ORG    0100H        ;Beginning for .COM programs
  28. START:        jmp    Initialize    ;Initialization code is at end
  29.  
  30. ;-----------------------------------------------------------------------
  31. ; Data needed by this program
  32. ;-----------------------------------------------------------------------
  33. HOTKEY        EQU    2EH        ;Scan code for "C" key
  34. SHIFT_MASK    EQU    00001000B    ;Mask for ALT key held down
  35.  
  36. COPYRIGHT    DB      "CAPTURE 1.0 (c) 1987 Ziff Communications Co"
  37.         DB    13,10,"Hotkey is ALT-C$",1Ah
  38. PROGRAMMER    DB      "Tom Kihlken"
  39. INSTALLED_MSG    DB    13,10,"Already Installed$"
  40. FILENAME    DB      "SCREEN.000",0  ;The first filename
  41. OLDINT09    DD    ?    ;Old hardware keyboard interrupt vector
  42. OLDINT13    DD    ?    ;Old BIOS disk IO interrupt vector
  43. OLDINT16    DD    ?    ;Old keyboard input interrupt vector
  44. OLDINT21    DD    ?    ;Old DOS function interrupt vector
  45. WRIT_FILE    DB    0    ;If=1, need to write to disk
  46. ACTIVE        DB    0    ;Indicated CAPTURE is in use
  47. DOS_STAT    DB    0    ;Current DOS function indicator
  48. BUSY_FLAGS    DB    0    ;Bit masked as follows:
  49.                 ;  1 - DOS function is active
  50.                 ;  2 - BIOS disk IO is active
  51.  
  52. ;-----------------------------------------------------------------------
  53. ; CAPTURE reads the screen and stores it in an internal buffer.
  54. ;-----------------------------------------------------------------------
  55. Capture        proc    NEAR
  56.         ASSUME  DS:CSEG, ES:BIOS_SEG
  57.  
  58.         call    Get_Curs_Addr        ;Cursor addr for this page
  59.         PUSH    ES:[BX]            ;Save the cursor location
  60.         mov    DI,OFFSET BUFFER    ;DS:DI points to the buffer
  61.         xor    DX,DX            ;Start at row 0, column 0
  62. Read_Loop:
  63.         cmp    DL,CRT_COLS    ;Past right edge of screen?
  64.         jl    Not_Past_Edge    ;If screen is less than 80
  65.         mov    AX,0720H    ;columns, then pad with a blank
  66.         jmp    SHORT Buff_Char
  67.  
  68. Not_Past_Edge:
  69.         call    Get_Curs_Addr    ;Get address of BIOS cursor
  70.         mov    ES:[BX],DX    ;Tell BIOS where the cursor is
  71.         mov    BH,ACTIVE_PAGE  ;Get active page from BIOS data
  72.         mov    AH,8        ;BIOS function to read character
  73.         int    10H        ;Read the character/attribute
  74. Buff_Char:
  75.         mov    [DI],AX        ;Put the character in buffer
  76.         inc    DI        ;Increment the pointer twice
  77.         inc    DI        ;Since we stored a word
  78.  
  79.         inc    DL        ;Do the next char in same row
  80.         cmp    DL,80        ;At the right border yet?
  81.         jl    Read_Loop    ;Do 80 characters in this row
  82.         inc    DH        ;Move to next row
  83.         xor    DL,DL        ;Back to left edge (Column 0)
  84.         cmp    DH,25        ;Done all 25 rows yet?
  85.         jl    Read_Loop    ;Loop until whole screen is read
  86.         call    Get_Curs_Addr    ;Cursor address for this page
  87.         POP    ES:[BX]        ;Recover the cursor position
  88.         RET            ;Then were finished
  89. Capture        ENDP
  90.  
  91. ;-----------------------------------------------------------------------
  92. ; This procedure obtains the address of the cursor position for this page
  93. ;-----------------------------------------------------------------------
  94. Get_Curs_Addr    proc    NEAR
  95.         ASSUME  DS:CSEG, ES:BIOS_SEG
  96.  
  97.         mov    BL,ACTIVE_PAGE  ;Get the current page number
  98.         xor    BH,BH        ;Convert to a word offset
  99.         SHL    BX,1        ;Times two for a word
  100.         ADD    BX,OFFSET CURSOR_POSN ;Add base cursor address
  101.         RET
  102.  
  103. Get_Curs_Addr    ENDP
  104.  
  105. ;-----------------------------------------------------------------------
  106. ; This copies the buffer contents to a file.  It should only be called
  107. ; when DOS is in a stable and reentrant condition.
  108. ;-----------------------------------------------------------------------
  109. Write_To_File    proc    NEAR
  110.         ASSUME  DS:NOTHING, ES:NOTHING
  111.  
  112.         mov    WRIT_FILE,0    ;Turn off request flag
  113.         STI            ;Get interrupts back on
  114.         push    AX        ;Must preserve all registers
  115.         push    BX
  116.         push    CX
  117.         push    DX
  118.         push    BP
  119.         push    DS
  120.         push    ES
  121.         push    CS
  122.         pop    DS
  123.         ASSUME  DS:CSEG        ;DS points to out code segment
  124.         mov    AX,3524H    ;Get DOS critical error vector
  125.         call    DOS_Function    ;Do the DOS function
  126.         push    BX        ;Save old INT 24 vector on stack
  127.         push    ES
  128.  
  129. ; Replace the DOS severe error interrupt with out own routine.
  130.  
  131.         mov    DX,OFFSET NewInt24
  132.         mov    AX,2524H    ;Setup to change INT 24h vector
  133.         call    DOS_Function    ;DOS function to change vector
  134.  
  135. ; Try to open the file to determine if it already exists.  If it does,
  136. ; then just close it and increment the filename.
  137.  
  138. Open_File:    mov    DX,OFFSET FILENAME    ;DS:DX points to filename
  139.         mov    AX,3D00H    ;Opin file for read access
  140.         call    DOS_Function    ;Do the DOS function
  141.         jc    Open_Error    ;If open error, take jump
  142.         mov    BX,AX        ;Need the handle in BX
  143.         mov    AH,3EH        ;Close this file
  144.         call    DOS_Function    ;Do the DOS function
  145.         call    Inc_Filename    ;Try the next filename
  146.         jmp    short Open_File
  147. Open_Error:
  148.         cmp    AX,2        ;Was it file not found error?
  149.         jne    DOS_Err_Exit    ;Exit on any other error
  150.  
  151. ; Now create the file, then write buffer contents and close it.
  152.  
  153.         mov    DX,OFFSET FILENAME    ;DS:DX points to filename
  154.         mov    CX,0020H    ;Attribute for new file
  155.         mov    AH,3CH        ;Create file for writing
  156.         call    DOS_Function    ;Do the DOS function
  157.         jc    Close_File    ;On any error, take jump
  158.  
  159.         mov    BX,AX        ;Save handle in BX
  160.         mov    DX,OFFSET BUFFER    ;Point to output buffer
  161.         mov    CX,4000        ;Write 4000 bytes
  162.         mov    AH,40H        ;DOS write to a device function
  163.         call    DOS_Function    ;Do the DOS function
  164. Close_File:
  165.         mov    AH,3EH        ;DOS function to close the file
  166.         call    DOS_Function    ;Do the DOS function
  167.         call    Inc_Filename    ;Move to next filename
  168.  
  169. DOS_Err_Exit:    pop    DS        ;Get INT 24H vector from stack
  170.         ASSUME  DS:NOTHING
  171.         pop    DX
  172.         mov    AX,2524H    ;Restore critical error vector
  173.         call    DOS_Function    ;Do the DOS function
  174.  
  175.         pop    ES        ;Finally restore all registers
  176.         pop    DS
  177.         pop    BP
  178.         pop    DX
  179.         pop    CX
  180.         pop    BX
  181.         pop    AX
  182.         mov    ACTIVE,0    ;CAPTURE is done now
  183.         RET            ;Finished writing to disk
  184.  
  185. Write_To_File    ENDP
  186.  
  187. ;-----------------------------------------------------------------------
  188. ; This routine does a dos function by calling the old interrupt vector
  189. ;-----------------------------------------------------------------------
  190.         ASSUME  DS:NOTHING, ES:NOTHING
  191. DOS_Function    proc    NEAR
  192.  
  193.         PUSHF            ;These instructions simulate
  194.         CLI            ;an interrupt
  195.         call    CS:OLDINT21    ;Do the DOS function
  196.         STI
  197.         RET
  198.  
  199. DOS_Function    ENDP
  200.  
  201. ;-----------------------------------------------------------------------
  202. ; This procedure increments the extension for the filename.
  203. ;-----------------------------------------------------------------------
  204. Inc_Filename    proc    NEAR
  205.         mov    BX,OFFSET FILENAME+9 ;Point to last letter
  206. Inc_Next_Char:
  207.         inc    BYTE PTR [BX]         ;Increment the extension
  208.         cmp    BYTE PTR [BX],"9"    ;Check for carry
  209.         jle    Inc_Return         ;If none, were finished
  210.         mov    BYTE PTR [BX],"0"    ;Set this digit to zero
  211.         dec    BX             ;Backup to next digit
  212.         cmp    BX,OFFSET FILENAME+6 ;Dont increment the dot
  213. ;        jle    Inc_Return
  214. ;        jmp    short Inc_Next_Char
  215.         ja    Inc_Next_Char    ;TH
  216. Inc_Return:
  217.         RET
  218. Inc_Filename    ENDP
  219.  
  220. ;-----------------------------------------------------------------------
  221. ; Interrupt 09 (Keyboard)  Watch for trigger key.  When found, ignore
  222. ; it and execute the CAPTURE routine.
  223. ;-----------------------------------------------------------------------
  224. NewInt09    proc    FAR
  225.         ASSUME  DS:NOTHING, ES:NOTHING
  226.  
  227.         STI            ;Allow other interrupts
  228.         push    AX        ;Must save processor state
  229.         IN    AL,60H        ;Get the scan code
  230.         cmp    AL,HOTKEY    ;Is it the hot key?
  231.         je    Trigger        ;If ye